package com.oig.sys.base.service.impl;

import cn.hutool.core.util.StrUtil;
import com.oig.common.constants.CommonEnum;
import com.oig.common.exception.BadRequestException;
import com.oig.common.module.SysPageInfo;
import com.oig.common.module.SysRequest;
import com.oig.sys.base.dao.ITbBankDao;
import com.oig.sys.base.dto.BankDto;
import com.oig.sys.base.entity.TbBank;
import com.oig.sys.base.service.ITbBankService;
import com.oig.sys.base.vo.BankVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @author wuxl
 */
@Service
public class TbBankServiceImpl implements ITbBankService {

	private final ITbBankDao tbBankDao;

	@Autowired
	public TbBankServiceImpl( ITbBankDao tbBankDao){
		 this.tbBankDao = tbBankDao;
	}

	@Transactional
	@Override
	public BankVo addTbBank(BankDto bankDto) {
		TbBank bank = this.tbBankDao.getByBankCode(bankDto.getBankCode());
		if (bank != null) {
			throw new BadRequestException("编码重复");
		}
		bank = new TbBank();
		BeanUtils.copyProperties(bankDto, bank);
		bank.setStatus(CommonEnum.CommonStatusEnum.OK.getCode());
		this.tbBankDao.save(bank) ;
		BankVo bankVo = new BankVo() ;
		BeanUtils.copyProperties(bank, bankVo);
		return bankVo;
	}

	@Transactional
	@Override
	public BankVo updateTbBank(BankDto bankDto) {
		TbBank bank = this.tbBankDao.getByBankCode(bankDto.getBankCode()) ;
		if (bank==null){
			throw new BadRequestException("记录不存在") ;
		}
		BeanUtils.copyProperties(bankDto, bank, "status");
		//code 数据库建唯一约束
		this.tbBankDao.save(bank) ;
		BankVo bankVo = new BankVo() ;
		BeanUtils.copyProperties(bank, bankVo);
		return bankVo;
	}

	@Transactional
	@Override
	public void cancelTbBank(String bankCode) {
		TbBank bank = this.tbBankDao.getByBankCode(bankCode) ;
		if (bank==null){
			throw new BadRequestException("记录不存在") ;
		}
		bank.setStatus(CommonEnum.CommonStatusEnum.DEL.getCode());
		this.tbBankDao.save(bank) ;
	}

	@Override
	public SysPageInfo<BankVo> findBank(SysRequest<BankDto> bankRequest) {
		Pageable pageable = bankRequest.pageable();
		Page<TbBank> page ;
		if (bankRequest.getParamDto()!=null){
			Specification<TbBank> specification = new Specification<TbBank>() {
				@Override
				@Nullable
				public Predicate toPredicate(@NonNull Root<TbBank> root, @NonNull CriteriaQuery<?> criteriaQuery, @NonNull CriteriaBuilder criteriaBuilder) {
					List<Predicate> predicateList = new ArrayList<>();
					Path<String> statusPath = root.get("status");
					if (StrUtil.isNotBlank(bankRequest.getParamDto().getStatus())) {
						predicateList.add(criteriaBuilder.equal(statusPath, bankRequest.getParamDto().getStatus()));
					} else {
						predicateList.add(criteriaBuilder.equal(statusPath, CommonEnum.CommonStatusEnum.OK.getCode()));
					}
					if (StrUtil.isNotBlank(bankRequest.getParamDto().getBankCode())) {
						Path<String> bankCodePath = root.get("bankCode");
						predicateList.add(criteriaBuilder.like(bankCodePath, "%" +bankRequest.getParamDto().getBankCode()+ "%"));
					}
					if (StrUtil.isNotBlank(bankRequest.getParamDto().getBankName())) {
						Path<String> bankNamePath = root.get("bankName");
						predicateList.add(criteriaBuilder.like(bankNamePath, "%" + bankRequest.getParamDto().getBankName() + "%"));
					}
					criteriaQuery.where(predicateList.toArray(new Predicate[0]));
					return criteriaQuery.getRestriction();
				}
			};
			page = this.tbBankDao.findAll(specification, pageable);
		} else {
			page = this.tbBankDao.findAll(pageable);
		}
		List<BankVo> bankVoList = new ArrayList<>();
		for (TbBank bank : page.getContent()){
			BankVo bankVo = new BankVo();
			BeanUtils.copyProperties(bank, bankVo);
			bankVoList.add(bankVo);
		}
		SysPageInfo<BankVo> sysPageInfo = new SysPageInfo<>(bankRequest.getPageNo(), bankRequest.getPageSize(), page.getTotalElements());
		sysPageInfo.setList(bankVoList);
		return sysPageInfo;
	}
}
